﻿using HtmlAgilityPack;
using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using UtilZ.Dotnet.Ex.Base;
using UtilZ.Dotnet.Ex.Log;

namespace LinuxSourcePkDownlader
{
    internal class KyGFBServerPkDownlader : PkDownladerAbs
    {
        protected readonly string _baseUrl = @"http://archive2.kylinos.cn/rpm/kylin/Library/custom/kylin-server/KY10-GFB-aarch64/Packages/";

        public KyGFBServerPkDownlader()
            : base("KyGFBServer")
        {

        }


        protected override void PrimitiveDownload(ThreadExPara threadPara, string dir)
        {
            using (HttpClient httpClient = base.CreateHttpClient())
            {
                Task<string> task;
                string htmlStr = null;

                Loger.Info("正在获取分组列表");
                while (!threadPara.Token.IsCancellationRequested)
                {
                    try
                    {
                        task = httpClient.GetStringAsync(this._baseUrl);
                        htmlStr = task.Result;
                        break;
                    }
                    catch (AggregateException aex)
                    {
                        Loger.Warn(aex);
                        threadPara.WaitOne(1000);
                    }
                    catch (HttpRequestException hrex)
                    {
                        Loger.Warn(hrex);
                        threadPara.WaitOne(1000);
                    }
                }
                if (threadPara.Token.IsCancellationRequested)
                {
                    return;
                }

                HtmlDocument doc = new HtmlDocument();
                doc.LoadHtml(htmlStr);
                //HtmlNode node = doc.DocumentNode.SelectSingleNode("/html/body/div[4]/div[1]/div[2]/ul[1]");
                var nodes = doc.DocumentNode.SelectNodes(@"//ul/li/a");
                Loger.Info($"获取分组列表完成,共{nodes.Count}个分组");

                string catigory, pkListUrl, pkDir;
                foreach (var node in nodes)
                {
                    if (threadPara.Token.IsCancellationRequested)
                    {
                        break;
                    }

                    catigory = node.GetAttributeValue("href", null);
                    if (string.IsNullOrWhiteSpace(catigory))
                    {
                        Loger.Info($"忽略{node.InnerText},因为href为空");
                        continue;
                    }

                    pkDir = PathEx.Combine(PathType.Local, dir, catigory);
                    DirectoryInfoEx.CheckDirectory(pkDir);

                    //http://archive2.kylinos.cn/rpm/kylin/Library/custom/kylin-server/KY10-GFB-aarch64/Packages/b/
                    pkListUrl = System.IO.Path.Combine(_baseUrl, catigory);
                    Loger.Info($"正在获取分组\"{node.InnerText}\"下包集合");
                    while (!threadPara.Token.IsCancellationRequested)
                    {
                        try
                        {
                            task = httpClient.GetStringAsync(pkListUrl);
                            htmlStr = task.Result;
                            break;
                        }
                        catch(AggregateException aex)
                        {
                            Loger.Warn(aex);
                            threadPara.WaitOne(1000);
                        }
                        catch (HttpRequestException hrex)
                        {
                            Loger.Warn(hrex);
                            threadPara.WaitOne(1000);
                        }
                    }
                    if (threadPara.Token.IsCancellationRequested)
                    {
                        break;
                    }
                    var doc2 = new HtmlDocument();
                    doc2.LoadHtml(htmlStr);
                    //HtmlNode node = doc.DocumentNode.SelectSingleNode("/html/body/div[4]/div[1]/div[2]/ul[1]");
                    var pkNodes = doc2.DocumentNode.SelectNodes(@"//ul/li/a");
                    Loger.Info($"获取分组\"{node.InnerText}\"下包集合完成,共{pkNodes.Count}个包");


                    Parallel.ForEach(pkNodes, (pkNode) =>
                    //foreach (var pkNode in pkNodes)
                    {
                        try
                        {
                            if (threadPara.Token.IsCancellationRequested)
                            {
                                return;
                            }

                            string pkName = pkNode.GetAttributeValue("href", null);
                            if (string.IsNullOrWhiteSpace(pkName))
                            {
                                Loger.Info($"忽略{pkNode.InnerText},因为href为空");
                                return;
                            }

                            Loger.Info($"下载包\"{catigory}{pkName}\"开始...");
                            //http://archive2.kylinos.cn/rpm/kylin/Library/custom/kylin-server/KY10-GFB-aarch64/Packages/b/b43-openfwwf-5.2-21.ky10.noarch.rpm
                            string pkUrl = Path.Combine(pkListUrl, pkName);
                            string pkFilePath = PathEx.Combine(PathType.Local, pkDir, pkName);
                            if (File.Exists(pkFilePath))
                            {
                                Loger.Info($"下载包\"{catigory}{pkName}\"已存在,忽略下载...");
                                //continue;
                                return;
                            }

                            using (HttpClient httpClient2 = base.CreateHttpClient())
                            {
                                using (Stream stream = httpClient2.GetStreamAsync(pkUrl).Result)
                                {
                                    using (var fs = File.Create(pkFilePath))
                                    {
                                        stream.CopyTo(fs);
                                    }
                                }
                            }
                            Loger.Info($"下载包\"{catigory}{pkName}\"完成...");
                        }
                        catch (Exception ex)
                        {
                            Loger.Error(ex, $"");
                        }
                    });
                    Loger.Info($"分组\"{node.InnerText}\"下包集合下载完成...");
                };

            }
        }



        protected override void Dispose(bool disposing)
        {

        }
    }
}
